CREATE OR REPLACE EDITIONABLE PACKAGE BODY "SCOTT"."PKG_MODEL_C_F_HOUR" is

  /*---------------------------------- calculate MACD's gold cross model --------------------------------------*/
  procedure CAL_MDL_MACD_GOLD_CROSS as
    -- 表示CODE
    v_code varchar2(100);
    -- 表示DATE
    v_date date;
    -- 表示两小时记录中的第一天，用于判断MACD是否发生了金叉或死叉
    v_first commodity_future_hour_data%rowtype;
    -- 表示两天记录中的第二天，用于判断MACD是否发生了金叉或死叉
    v_second commodity_future_hour_data%rowtype;
    -- 作为临时变量，表示CODE,BUY_TIME,SELL_TIME,BUY_PRICE,SELL_PRICE,BUY_DIF,BUY_DEA,SELL_DIF,SELL_DEA
    v_temp_code       varchar2(100);
    v_temp_buy_time   date;
    v_temp_sell_time  date;
    v_temp_buy_price  number;
    v_temp_sell_price number;
    v_temp_buy_dif    number;
    v_temp_buy_dea    number;
    v_temp_sell_dif   number;
    v_temp_sell_dea   number;
    -- 用来判断现在是否是dif>dea的阶段，从而可以判断死叉
    v_start_track_gold_cross_stage number;
    -- 用来表示金叉和死叉是否发现了
    v_gold_cross_found  number;
    v_death_cross_found number;
    -- 每只期货初始的accumulative_profit_loss值为100（表示百分之一百），之后代表上一次交易的累计盈亏百分比
    v_init_last_acc_profit_loss number;
    -- 表示字段PROFIT_LOSS的临时变量
    v_temp_profit_loss number;
    -- 用于获取所有的CODE
    cursor cur_all_code is
      select distinct t.code from commodity_future_hour_data t; -- where t.code_ like '000%' or t.code_ like '300%' or t.code_ like '600%' or t.code_ like '603%';
    /*
    stock_transaction_data表中一共有code_：3963
    select count(distinct t.code_) from stock_transaction_data t where t.code_ like '000%'; 完成 -- 452
    select count(distinct t.code_) from stock_transaction_data t where t.code_ like '001%'; 完成 -- 6
    select count(distinct t.code_) from stock_transaction_data t where t.code_ like '002%'; 完成 -- 962
    select count(distinct t.code_) from stock_transaction_data t where t.code_ like '003%'; 完成 -- 1
    select count(distinct t.code_) from stock_transaction_data t where t.code_ like '300%'; 完成 -- 853
    select count(distinct t.code_) from stock_transaction_data t where t.code_ like '600%'; 完成 -- 809
    select count(distinct t.code_) from stock_transaction_data t where t.code_ like '601%'; 完成 -- 201
    select count(distinct t.code_) from stock_transaction_data t where t.code_ like '603%'; 完成 -- 510
    select count(distinct t.code_) from stock_transaction_data t where t.code_ like '688%'; 完成 -- 169
            */
    -- 用于根据CODE获取某一只期货的所有交易记录
    cursor cur_single is
      select *
        from commodity_future_hour_data t
       where t.code = v_code
       order by t.end_time asc;
    -- 用于获取某一只期货两小时的交易记录，用于判断MACD是否发生了金叉或死叉
    cursor cur_single_two_record is
      select *
        from (select *
                from commodity_future_hour_data t
               where t.end_time >= v_date
                 and t.code = v_code
               order by t.end_time asc)
       where rownum <= 2;
  begin
    for i in cur_all_code loop
      v_code                         := i.code;
      v_init_last_acc_profit_loss    := 100;
      v_start_track_gold_cross_stage := 0;
      for j in cur_single loop
        v_date := j.end_time;
        -- 如果最早的数据是dif>dea，那么接下来只有可能先出现死叉，所以要判断：j.dif<j.dea，也就是说如果第一段数据是dif>dea，则将其忽略
        -- 之后在确认了金叉后，需要确认死叉，所以引入了表示变量v_start_track_gold_cross_stage，当其为1时，表示接下来只可能出现死叉
        if j.dif < j.dea or
           (j.dif > j.dea and v_start_track_gold_cross_stage = 1) then
          -- 分别将两小时的记录赋给相应的变量
          for x in cur_single_two_record loop
            if cur_single_two_record%rowcount = 1 then
              v_first := x;
            elsif cur_single_two_record%rowcount = 2 then
              v_second := x;
            end if;
          end loop;
          -- 如果出现了金叉，给临时变量赋值
          if v_first.dif < v_first.dea and v_second.dif > v_second.dea and
             v_start_track_gold_cross_stage = 0 then
            v_temp_code        := v_second.code;
            v_temp_buy_time    := v_second.end_time;
            v_temp_buy_price   := v_second.close_price;
            v_temp_buy_dif     := v_second.dif;
            v_temp_buy_dea     := v_second.dea;
            v_gold_cross_found := 1;
            -- 当金叉发生后，只可能发生死叉，因此要将v_start_track_gold_cross_stage设置为1
            v_start_track_gold_cross_stage := 1;
          
            -- dbms_output.put_line('gold cross   ' || j.end_time);
          end if;
          -- 如果出现了死叉，给临时变量赋值
          if v_first.dif > v_first.dea and v_second.dif < v_second.dea and
             v_start_track_gold_cross_stage = 1 then
            v_temp_sell_time    := v_second.end_time;
            v_temp_sell_price   := v_second.close_price;
            v_temp_sell_dif     := v_second.dif;
            v_temp_sell_dea     := v_second.dea;
            v_death_cross_found := 1;
            -- 当死叉发生后，只可能发生金叉，因此要将v_start_track_gold_cross_stage设置为0
            v_start_track_gold_cross_stage := 0;
          
            -- dbms_output.put_line('death cross   ' || j.end_time);
          end if;
          -- 插入数据。要求这只期货在开始时间和结束时间内没有停牌或除权的情况
          if v_gold_cross_found = 1 and v_death_cross_found = 1 and
             v_temp_buy_time is not null and v_temp_sell_time is not null and
             v_temp_code is not null then
            v_temp_profit_loss          := round((v_temp_sell_price -
                                                 v_temp_buy_price) /
                                                 v_temp_buy_price,
                                                 4) * 100;
            v_init_last_acc_profit_loss := v_init_last_acc_profit_loss *
                                           (1 + v_temp_profit_loss / 100);
            begin
              insert into MDL_C_F_HOUR_MACD_GOLD_CROSS
                (buy_time,
                 sell_time,
                 buy_price,
                 sell_price,
                 profit_loss,
                 code,
                 accumulative_profit_loss,
                 buy_dif,
                 buy_dea,
                 sell_dif,
                 sell_dea)
              values
                (v_temp_buy_time,
                 v_temp_sell_time,
                 v_temp_buy_price,
                 v_temp_sell_price,
                 v_temp_profit_loss,
                 v_temp_code,
                 --round(v_init_last_acc_profit_loss, 32),
                 v_init_last_acc_profit_loss,
                 v_temp_buy_dif,
                 v_temp_buy_dea,
                 v_temp_sell_dif,
                 v_temp_sell_dea);
            exception
              when others then
                dbms_output.put_line('v_init_last_acc_profit_loss为【' ||
                                     v_init_last_acc_profit_loss || '】');
                dbms_output.put_line('round(v_init_last_acc_profit_loss, 32)为【' ||
                                     round(v_init_last_acc_profit_loss, 32) || '】');
            end;
            v_gold_cross_found  := 0;
            v_death_cross_found := 0;
          end if;
        end if;
      end loop;
    end loop;
    commit;
  end CAL_MDL_MACD_GOLD_CROSS;

  /*---------------------------------- calculate MACD's gold cross model incrementaly ------------------------------------*/
  procedure CAL_MDL_MACD_GOLD_CROSS_INCR(p_end_date in varchar2) as
    -- 表示CODE
    v_code varchar2(100);
    -- 表示DATE
    v_date date;
    -- 表示两小时记录中的第一小时，用于判断MACD是否发生了金叉或死叉
    v_first commodity_future_hour_data%rowtype;
    -- 表示两小时记录中的第二小时，用于判断MACD是否发生了金叉或死叉
    v_second commodity_future_hour_data%rowtype;
    -- 作为临时变量，表示CODE,BUY_TIME,SELL_TIME,BUY_PRICE,SELL_PRICE,BUY_DIF,BUY_DEA,SELL_DIF,SELL_DEA
    v_temp_code       varchar2(100);
    v_temp_buy_time   date;
    v_temp_sell_time  date;
    v_temp_buy_price  number;
    v_temp_sell_price number;
    v_temp_buy_dif    number;
    v_temp_buy_dea    number;
    v_temp_sell_dif   number;
    v_temp_sell_dea   number;
    -- 用来判断现在是否是dif>dea的阶段，从而可以判断死叉
    v_start_track_gold_cross_stage number;
    -- 用来表示金叉和死叉是否发现了
    v_gold_cross_found  number := 0;
    v_death_cross_found number := 0;
    -- 每只期货初始的accumulative_profit_loss值为100（表示百分之一百），之后代表上一次交易的累计盈亏百分比
    v_init_last_acc_profit_loss number;
    -- 表示字段PROFIT_LOSS的临时变量
    v_temp_profit_loss number;
    -- 用于获取所有的CODE
    cursor cur_all_code is
      select distinct t.code from commodity_future_hour_data t;
    -- 用于根据CODE获取某一只期货的所有交易记录。
    -- 1997-01-commodity_future_hour_data。
    -- buy_time和sell_time效果一样
    cursor cur_single is
      select *
        from commodity_future_hour_data t1
       where t1.end_time >
             (select nvl(max(t.buy_time),
                         to_date('1997-01-01', 'yyyy-mm-dd'))
                from mdl_c_f_hour_macd_gold_cross t
               where t.code = v_code)
         and t1.end_time <= to_date(p_end_date, 'yyyy-mm-dd')
         and t1.code = v_code
       order by t1.end_time asc;
    -- 用于获取某一只期货两小时的交易记录，用于判断MACD是否发生了金叉或死叉
    cursor cur_single_two_record is
      select *
        from (select *
                from commodity_future_hour_data t
               where t.end_time >= v_date
                 and t.code = v_code
               order by t.end_time asc)
       where rownum <= 2;
  begin
    for i in cur_all_code loop
      v_code                         := i.code;
      v_init_last_acc_profit_loss    := 100;
      v_start_track_gold_cross_stage := 0;
      for j in cur_single loop
        v_date := j.end_time;
        -- 如果最早的数据是dif>dea，那么接下来只有可能先出现死叉，所以要判断：j.dif<j.dea，也就是说如果第一段数据是dif>dea，则将其忽略
        -- 之后在确认了金叉后，需要确认死叉，所以引入了表示变量v_start_track_gold_cross_stage，当其为1时，表示接下来只可能出现死叉
        if j.dif < j.dea or
           (j.dif > j.dea and v_start_track_gold_cross_stage = 1) then
          -- 分别将两小时的记录赋给相应的变量
          for x in cur_single_two_record loop
            if cur_single_two_record%rowcount = 1 then
              v_first := x;
            elsif cur_single_two_record%rowcount = 2 then
              v_second := x;
            end if;
          end loop;
          -- 如果出现了金叉，给临时变量赋值
          if v_first.dif < v_first.dea and v_second.dif > v_second.dea and
             v_start_track_gold_cross_stage = 0 then
            v_temp_code        := v_second.code;
            v_temp_buy_time    := v_second.end_time;
            v_temp_buy_price   := v_second.close_price;
            v_temp_buy_dif     := v_second.dif;
            v_temp_buy_dea     := v_second.dea;
            v_gold_cross_found := 1;
            -- 当金叉发生后，只可能发生死叉，因此要将v_start_track_gold_cross_stage设置为1
            v_start_track_gold_cross_stage := 1;
          
          end if;
          -- 如果出现了死叉，给临时变量赋值
          if v_first.dif > v_first.dea and v_second.dif < v_second.dea and
             v_start_track_gold_cross_stage = 1 then
            v_temp_sell_time    := v_second.end_time;
            v_temp_sell_price   := v_second.close_price;
            v_temp_sell_dif     := v_second.dif;
            v_temp_sell_dea     := v_second.dea;
            v_death_cross_found := 1;
            -- 当死叉发生后，只可能发生金叉，因此要将v_start_track_gold_cross_stage设置为0
            v_start_track_gold_cross_stage := 0;
          
          end if;
          -- 插入数据
          if v_gold_cross_found = 1 and v_death_cross_found = 1 and
             v_temp_buy_time is not null and v_temp_sell_time is not null and
             v_temp_code is not null then
            v_temp_profit_loss := round((v_temp_sell_price -
                                        v_temp_buy_price) /
                                        v_temp_buy_price,
                                        4) * 100;
            -- 获取最近一次交易后的accumulative_profit_loss
            begin
              select t.accumulative_profit_loss
                into v_init_last_acc_profit_loss
                from (select *
                        from mdl_c_f_hour_macd_gold_cross t
                       where t.code = v_code
                       order by t.buy_time desc) t
               where rownum <= 1;
            exception
              when no_data_found then
                dbms_output.put_line('code为【' || v_code || '】，
                                                            在mdl_c_f_hour_macd_gold_cross表中没有记录');
            end;
            -- 计算本次交易后的accumulative_profit_loss
            v_init_last_acc_profit_loss := v_init_last_acc_profit_loss *
                                           (1 + v_temp_profit_loss / 100);
          
            insert into MDL_C_F_HOUR_MACD_GOLD_CROSS
              (buy_time,
               sell_time,
               buy_price,
               sell_price,
               profit_loss,
               code,
               accumulative_profit_loss,
               buy_dif,
               buy_dea,
               sell_dif,
               sell_dea)
            values
              (v_temp_buy_time,
               v_temp_sell_time,
               v_temp_buy_price,
               v_temp_sell_price,
               v_temp_profit_loss,
               v_temp_code,
               --round(v_init_last_acc_profit_loss, 32),
               v_init_last_acc_profit_loss,
               v_temp_buy_dif,
               v_temp_buy_dea,
               v_temp_sell_dif,
               v_temp_sell_dea);
          
            v_gold_cross_found  := 0;
            v_death_cross_found := 0;
          end if;
        end if;
      end loop;
    end loop;
    commit;
  end CAL_MDL_MACD_GOLD_CROSS_INCR;

  /*---------------------------------- calculate MACD's dead cross model --------------------------------------*/
  procedure CAL_MDL_MACD_DEAD_CROSS as
    -- 表示CODE
    v_code varchar2(100);
    -- 表示DATE
    v_date date;
    -- 表示两小时记录中的第一小时，用于判断MACD是否发生了金叉或死叉
    v_first commodity_future_hour_data%rowtype;
    -- 表示两小时记录中的第二小时，用于判断MACD是否发生了金叉或死叉
    v_second commodity_future_hour_data%rowtype;
    -- 作为临时变量，表示CODE,BUY_TIME,SELL_TIME,BUY_PRICE,SELL_PRICE,BUY_DIF,BUY_DEA,SELL_DIF,SELL_DEA
    v_temp_code       varchar2(100);
    v_temp_buy_time   date;
    v_temp_sell_time  date;
    v_temp_buy_price  number;
    v_temp_sell_price number;
    v_temp_buy_dif    number;
    v_temp_buy_dea    number;
    v_temp_sell_dif   number;
    v_temp_sell_dea   number;
    -- 用来判断现在是否是dif>dea的阶段，从而可以判断死叉
    v_start_track_dead_cross_stage number;
    -- 用来表示金叉和死叉是否发现了
    v_gold_cross_found number;
    v_dead_cross_found number;
    -- 每只期货初始的accumulative_profit_loss值为100（表示百分之一百），之后代表上一次交易的累计盈亏百分比
    v_init_last_acc_profit_loss number;
    -- 表示字段PROFIT_LOSS的临时变量
    v_temp_profit_loss number;
    -- 用于获取所有的CODE
    cursor cur_all_code is
      select distinct t.code from commodity_future_hour_data t;
    /*where t.code_ not like '000%' and t.code_ not like '001%' and t.code_ not like '002%' 
    and t.code_ not like '003%' and t.code_ not like '300%' and t.code_ not like '600%'
    and t.code_ not like '601%' and t.code_ not like '603%' and t.code_ not like '688%';*/
    /*
    select distinct t.code_ from stock_transaction_data_all t;                         -- 4194
    select count(distinct t.code_) from stock_transaction_data_all t where t.code_ like '000%'; -- 完成 450
    select count(distinct t.code_) from stock_transaction_data_all t where t.code_ like '001%'; -- 完成 6
    select count(distinct t.code_) from stock_transaction_data_all t where t.code_ like '002%'; -- 完成 961
    select count(distinct t.code_) from stock_transaction_data_all t where t.code_ like '003%'; -- 完成 38
    select count(distinct t.code_) from stock_transaction_data_all t where t.code_ like '300%'; -- 完成 915
    select count(distinct t.code_) from stock_transaction_data_all t where t.code_ like '600%'; -- 完成 801
    select count(distinct t.code_) from stock_transaction_data_all t where t.code_ like '601%'; -- 完成 207
    select count(distinct t.code_) from stock_transaction_data_all t where t.code_ like '603%'; -- 完成 513
    select count(distinct t.code_) from stock_transaction_data_all t where t.code_ like '688%'; -- 完成 235
    -- 其他 68
            */
    -- 用于根据CODE获取某一只期货的所有交易记录
    cursor cur_single is
      select *
        from commodity_future_hour_data t
       where t.code = v_code
       order by t.end_time asc;
    -- 用于获取某一只期货两小时的交易记录，用于判断MACD是否发生了金叉或死叉
    cursor cur_single_two_record is
      select *
        from (select *
                from commodity_future_hour_data t
               where t.end_time >= v_date
                 and t.code = v_code
               order by t.end_time asc)
       where rownum <= 2;
  begin
    for i in cur_all_code loop
      v_code                         := i.code;
      v_init_last_acc_profit_loss    := 100;
      v_start_track_dead_cross_stage := 0;
      for j in cur_single loop
        v_date := j.end_time;
        -- 如果最早的数据是dif<dea，那么接下来只有可能先出现金叉，所以要判断：j.dif>j.dea，也就是说如果第一段数据是dif<dea，则将其忽略
        -- 之后在确认了死叉后，需要确认金叉，所以引入了表示变量v_start_track_dead_cross_stage，当其为1时，表示接下来只可能出现金叉
        if j.dif > j.dea or
           (j.dif < j.dea and v_start_track_dead_cross_stage = 1) then
          -- 分别将两小时的记录赋给相应的变量
          for x in cur_single_two_record loop
            if cur_single_two_record%rowcount = 1 then
              v_first := x;
            elsif cur_single_two_record%rowcount = 2 then
              v_second := x;
            end if;
          end loop;
          -- 如果出现了死叉，给临时变量赋值
          if v_first.dif > v_first.dea and v_second.dif < v_second.dea and
             v_start_track_dead_cross_stage = 0 then
            v_temp_code        := v_second.code;
            v_temp_sell_time   := v_second.end_time;
            v_temp_sell_price  := v_second.close_price;
            v_temp_sell_dif    := v_second.dif;
            v_temp_sell_dea    := v_second.dea;
            v_gold_cross_found := 1;
            -- 当死叉发生后，只可能发生金叉，因此要将v_start_track_dead_cross_stage设置为1
            v_start_track_dead_cross_stage := 1;
          
            -- dbms_output.put_line('dead cross   ' || j.end_time);
          end if;
          -- 如果出现了金叉，给临时变量赋值
          if v_first.dif < v_first.dea and v_second.dif > v_second.dea and
             v_start_track_dead_cross_stage = 1 then
            v_temp_buy_time    := v_second.end_time;
            v_temp_buy_price   := v_second.close_price;
            v_temp_buy_dif     := v_second.dif;
            v_temp_buy_dea     := v_second.dea;
            v_dead_cross_found := 1;
            -- 当金叉发生后，只可能发生死叉，因此要将v_start_track_dead_cross_stage设置为0
            v_start_track_dead_cross_stage := 0;
          
            -- dbms_output.put_line('gold cross   ' || j.end_time);
          end if;
          -- 插入数据。要求这只期货在开始时间和结束时间内没有停牌或除权的情况
          if v_gold_cross_found = 1 and v_dead_cross_found = 1 and
             v_temp_sell_time is not null and v_temp_buy_time is not null and
             v_temp_code is not null then
            v_temp_profit_loss          := round((v_temp_sell_price -
                                                 v_temp_buy_price) /
                                                 v_temp_sell_price,
                                                 4) * 100;
            v_init_last_acc_profit_loss := v_init_last_acc_profit_loss *
                                           (1 + v_temp_profit_loss / 100);
          
            insert into MDL_C_F_HOUR_MACD_DEAD_CROSS
              (buy_time,
               sell_time,
               buy_price,
               sell_price,
               profit_loss,
               code,
               accumulative_profit_loss,
               buy_dif,
               buy_dea,
               sell_dif,
               sell_dea)
            values
              (v_temp_buy_time,
               v_temp_sell_time,
               v_temp_buy_price,
               v_temp_sell_price,
               v_temp_profit_loss,
               v_temp_code,
               --round(v_init_last_acc_profit_loss, 32),
               v_init_last_acc_profit_loss,
               v_temp_buy_dif,
               v_temp_buy_dea,
               v_temp_sell_dif,
               v_temp_sell_dea);
            commit;
          
            v_gold_cross_found := 0;
            v_dead_cross_found := 0;
          end if;
        end if;
      end loop;
    end loop;
  
  end CAL_MDL_MACD_DEAD_CROSS;

  /*---------------------------------- calculate MACD's dead cross model incrementaly ------------------------------------*/
  procedure CAL_MDL_MACD_DEAD_CROSS_INCR(p_end_date in varchar2) as
    -- 表示CODE
    v_code varchar2(100);
    -- 表示DATE
    v_date date;
    -- 表示两小时记录中的第一小时，用于判断MACD是否发生了金叉或死叉
    v_first commodity_future_hour_data%rowtype;
    -- 表示两小时记录中的第二小时，用于判断MACD是否发生了金叉或死叉
    v_second commodity_future_hour_data%rowtype;
    -- 作为临时变量，表示CODE,BUY_TIME,SELL_TIME,BUY_PRICE,SELL_PRICE,BUY_DIF,BUY_DEA,SELL_DIF,SELL_DEA
    v_temp_code       varchar2(100);
    v_temp_buy_time   date;
    v_temp_sell_time  date;
    v_temp_buy_price  number;
    v_temp_sell_price number;
    v_temp_buy_dif    number;
    v_temp_buy_dea    number;
    v_temp_sell_dif   number;
    v_temp_sell_dea   number;
    -- 用来判断现在是否是dif<dea的阶段，从而可以判断金叉
    v_start_track_dead_cross_stage number;
    -- 用来表示金叉和死叉是否发现了
    v_gold_cross_found number := 0;
    v_dead_cross_found number := 0;
    -- 每只期货初始的accumulative_profit_loss值为100（表示百分之一百），之后代表上一次交易的累计盈亏百分比
    v_init_last_acc_profit_loss number;
    -- 表示字段PROFIT_LOSS的临时变量
    v_temp_profit_loss number;
    -- 用于获取所有的CODE
    cursor cur_all_code is
      select distinct t.code from commodity_future_hour_data t;
    -- 用于根据STOCK_CODE获取某一只期货的所有交易记录。
    -- 1997-01-01是commodity_future_hour_data表中最早的交易记录。
    -- buy_time和sell_time效果一样
    cursor cur_single is
      select *
        from commodity_future_hour_data t1
       where t1.end_time >
             (select nvl(max(t.sell_time),
                         to_date('1997-01-01', 'yyyy-mm-dd'))
                from mdl_c_f_hour_macd_dead_cross t
               where t.code = v_code)
         and t1.end_time <= to_date(p_end_date, 'yyyy-mm-dd')
         and t1.code = v_code
       order by t1.end_time asc;
    -- 用于获取某一只期货两小时的交易记录，用于判断MACD是否发生了金叉或死叉
    cursor cur_single_two_record is
      select *
        from (select *
                from commodity_future_hour_data t
               where t.end_time >= v_date
                 and t.code = v_code
               order by t.end_time asc)
       where rownum <= 2;
  begin
    for i in cur_all_code loop
      v_code                         := i.code;
      v_init_last_acc_profit_loss    := 100;
      v_start_track_dead_cross_stage := 0;
      for j in cur_single loop
        v_date := j.end_time;
        -- 如果最早的数据是dif<dea，那么接下来只有可能先出现金叉，所以要判断：j.dif>j.dea，也就是说如果第一段数据是dif<dea，则将其忽略
        -- 之后在确认了死叉后，需要确认金叉，所以引入了表示变量v_start_track_dead_cross_stage，当其为1时，表示接下来只可能出现金叉
        if j.dif > j.dea or
           (j.dif < j.dea and v_start_track_dead_cross_stage = 1) then
          -- 分别将两小时的记录赋给相应的变量
          for x in cur_single_two_record loop
            if cur_single_two_record%rowcount = 1 then
              v_first := x;
            elsif cur_single_two_record%rowcount = 2 then
              v_second := x;
            end if;
          end loop;
          -- 如果出现了金叉，给临时变量赋值
          if v_first.dif < v_first.dea and v_second.dif > v_second.dea and
             v_start_track_dead_cross_stage = 1 then
            v_temp_code        := v_second.code;
            v_temp_buy_time    := v_second.end_time;
            v_temp_buy_price   := v_second.close_price;
            v_temp_buy_dif     := v_second.dif;
            v_temp_buy_dea     := v_second.dea;
            v_gold_cross_found := 1;
            -- 当金叉发生后，只可能发生死叉，因此要将v_start_track_dead_cross_stage设置为0
            v_start_track_dead_cross_stage := 0;
          
          end if;
          -- 如果出现了死叉，给临时变量赋值
          if v_first.dif > v_first.dea and v_second.dif < v_second.dea and
             v_start_track_dead_cross_stage = 0 then
            v_temp_sell_time   := v_second.end_time;
            v_temp_sell_price  := v_second.close_price;
            v_temp_sell_dif    := v_second.dif;
            v_temp_sell_dea    := v_second.dea;
            v_dead_cross_found := 1;
            -- 当死叉发生后，只可能发生金叉，因此要将v_start_track_dead_cross_stage设置为1
            v_start_track_dead_cross_stage := 1;
          
          end if;
          -- 插入数据
          if v_gold_cross_found = 1 and v_dead_cross_found = 1 and
             v_temp_buy_time is not null and v_temp_sell_time is not null and
             v_temp_code is not null then
            v_temp_profit_loss := round((v_temp_sell_price -
                                        v_temp_buy_price) /
                                        v_temp_sell_price,
                                        4) * 100;
            -- 获取最近一次交易后的accumulative_profit_loss
            begin
              select t.accumulative_profit_loss
                into v_init_last_acc_profit_loss
                from (select *
                        from mdl_c_f_hour_macd_dead_cross t
                       where t.code = v_code
                       order by t.buy_time desc) t
               where rownum <= 1;
            exception
              when no_data_found then
                dbms_output.put_line('code为【' || v_code || '】，
                                                            在mdl_c_f_hour_macd_dead_cross表中没有记录');
            end;
            -- 计算本次交易后的accumulative_profit_loss
            v_init_last_acc_profit_loss := v_init_last_acc_profit_loss *
                                           (1 + v_temp_profit_loss / 100);
          
            insert into MDL_C_F_HOUR_MACD_DEAD_CROSS
              (buy_time,
               sell_time,
               buy_price,
               sell_price,
               profit_loss,
               code,
               accumulative_profit_loss,
               buy_dif,
               buy_dea,
               sell_dif,
               sell_dea)
            values
              (v_temp_buy_time,
               v_temp_sell_time,
               v_temp_buy_price,
               v_temp_sell_price,
               v_temp_profit_loss,
               v_temp_code,
               --round(v_init_last_acc_profit_loss, 32),
               v_init_last_acc_profit_loss,
               v_temp_buy_dif,
               v_temp_buy_dea,
               v_temp_sell_dif,
               v_temp_sell_dea);
          
            v_gold_cross_found := 0;
            v_dead_cross_found := 0;
          end if;
        end if;
      end loop;
    end loop;
    commit;
  end CAL_MDL_MACD_DEAD_CROSS_INCR;

  /*---------------------------------- 海量地向表MDL_C_F_HOUR_C_P_MA_G_C中插入数据 --------------------------------------*/
  procedure CAL_MDL_CF_HOUR_CP_MA_GC as
    -- 表示CODE
    v_code varchar2(100);
    -- 作为临时变量，表示CODE,BUY_TIME,SELL_TIME,BUY_PRICE,SELL_PRICE,BUY_MA5,SELL_MA5
    v_temp_code       varchar2(100);
    v_temp_buy_time   date;
    v_temp_sell_time  date;
    v_temp_buy_price  number;
    v_temp_sell_price number;
    v_temp_buy_ma5    number;
    v_temp_sell_ma5   number;
    -- 1表示close_price>ma5的阶段，2表示close_price<=ma5的阶段
    v_start_track_gold_cross_stage number;
    -- 每只期货初始的accumulative_profit_loss值为100（表示百分之一百），之后代表上一次交易的累计盈亏百分比
    v_init_last_acc_profit_loss number;
    -- 表示字段PROFIT_LOSS的临时变量
    v_temp_profit_loss number;
    -- 用于获取所有的CODE
    cursor cur_all_code is
      select distinct t.code from commodity_future_hour_data t;
    -- 用于根据CODE获取某一只期货的所有交易记录
    cursor cur_single is
      select *
        from commodity_future_hour_data t
       where t.code = v_code
       order by t.end_time asc;
  begin
    for i in cur_all_code loop
      v_code                         := i.code;
      v_init_last_acc_profit_loss    := 100;
      v_start_track_gold_cross_stage := 0;
    
      for j in cur_single loop
        if j.close_price > j.ma5 then
          if v_start_track_gold_cross_stage = 0 then
            -- 买入
            v_temp_code                    := j.code;
            v_temp_buy_time                := j.end_time;
            v_temp_buy_price               := j.close_price;
            v_temp_buy_ma5                 := j.ma5;
            v_start_track_gold_cross_stage := 1;
          else
            continue;
          end if;
        end if;
      
        if j.close_price <= j.ma5 then
          if v_start_track_gold_cross_stage = 1 then
            -- 卖出
            v_temp_sell_time            := j.end_time;
            v_temp_sell_price           := j.close_price;
            v_temp_sell_ma5             := j.ma5;
            v_temp_profit_loss          := round((v_temp_sell_price -
                                                 v_temp_buy_price) /
                                                 v_temp_buy_price,
                                                 4) * 100;
            v_init_last_acc_profit_loss := v_init_last_acc_profit_loss *
                                           (1 + v_temp_profit_loss / 100);
            -- 插入记录
            insert into mdl_c_f_hour_c_p_ma5_g_c
              (buy_time,
               sell_time,
               buy_price,
               sell_price,
               profit_loss,
               code,
               accumulative_profit_loss,
               buy_ma5,
               sell_ma5)
            values
              (v_temp_buy_time,
               v_temp_sell_time,
               v_temp_buy_price,
               v_temp_sell_price,
               v_temp_profit_loss,
               v_temp_code,
               v_init_last_acc_profit_loss,
               v_temp_buy_ma5,
               v_temp_sell_ma5);
          
            -- 重置为0，表示还没有买入
            v_start_track_gold_cross_stage := 0;
          else
            continue;
          end if;
        end if;
      end loop;
    end loop;
    commit;
  end CAL_MDL_CF_HOUR_CP_MA_GC;

  /*---------------------------------- 增量地向表MDL_C_F_HOUR_C_P_MA_G_C中插入数据 ------------------------------------*/
  procedure CAL_MDL_CF_HOUR_CP_MA_GC_INCR(p_end_date in varchar2) as
    -- 表示CODE
    v_code varchar2(100);
    -- 作为临时变量，表示CODE,BUY_TIME,SELL_TIME,BUY_PRICE,SELL_PRICE,BUY_MA5,SELL_MA5
    v_temp_code       varchar2(100);
    v_temp_buy_time   date;
    v_temp_sell_time  date;
    v_temp_buy_price  number;
    v_temp_sell_price number;
    v_temp_buy_ma5    number;
    v_temp_sell_ma5   number;
    -- 1表示close_price>ma5的阶段，0表示close_price<=ma5的阶段
    v_start_track_gold_cross_stage number;
    -- 每只期货初始的accumulative_profit_loss值为100（表示百分之一百），之后代表上一次交易的累计盈亏百分比
    v_init_last_acc_profit_loss number;
    -- 表示字段PROFIT_LOSS的临时变量
    v_temp_profit_loss number;
    -- 用于获取所有的CODE
    cursor cur_all_code is
      select distinct t.code from commodity_future_hour_data t;
    -- 从某一只期货在mdl_c_f_hour_c_p_ma5_g_c表中最后的卖出日期，到参数p_end_date之间的交易记录，
    -- 并按升序排列。这段时间内可能存在先是close_price金叉ma5，然后close_price死叉ma5。
    -- buy_time和sell_time效果一样
    cursor cur_c_p_gold_dead_cross_ma5 is
      select *
        from commodity_future_hour_data t
       where t.code = v_code
         and t.end_time >
             (select max(mcfdcpmgc.sell_time)
                from mdl_c_f_hour_c_p_ma5_g_c mcfdcpmgc
               where mcfdcpmgc.code = v_code)
         and t.end_time <= to_date(p_end_date, 'yyyy-mm-dd')
       order by t.end_time asc;
  begin
    for i in cur_all_code loop
      v_code                         := i.code;
      v_start_track_gold_cross_stage := 0;
      -- 查找最近的accumulative_profit_loss
      begin
        select b.accumulative_profit_loss
          into v_init_last_acc_profit_loss
          from (select *
                  from mdl_c_f_hour_c_p_ma5_g_c t
                 where t.code = v_code
                 order by t.sell_time desc) b
         where rownum <= 1;
      exception
        when no_data_found then
          dbms_output.put_line('code为【' || v_code || '】，
                                                            在mdl_c_f_hour_c_p_ma5_g_c表中没有记录');
      end;
    
      for j in cur_c_p_gold_dead_cross_ma5 loop
        if j.close_price > j.ma5 then
          -- 买入
          if v_start_track_gold_cross_stage = 0 then
            v_temp_code                    := j.code;
            v_temp_buy_time                := j.end_time;
            v_temp_buy_price               := j.close_price;
            v_temp_buy_ma5                 := j.ma5;
            v_start_track_gold_cross_stage := 1;
          else
            continue;
          end if;
        end if;
      
        if j.close_price <= j.ma5 then
          -- 卖出
          if v_start_track_gold_cross_stage = 1 then
            v_temp_sell_time  := j.end_time;
            v_temp_sell_price := j.close_price;
            v_temp_sell_ma5   := j.ma5;
          
            v_temp_profit_loss          := round((v_temp_sell_price -
                                                 v_temp_buy_price) /
                                                 v_temp_buy_price,
                                                 4) * 100;
            v_init_last_acc_profit_loss := v_init_last_acc_profit_loss *
                                           (1 + v_temp_profit_loss / 100);
          
            insert into mdl_c_f_hour_c_p_ma5_g_c
              (buy_time,
               sell_time,
               buy_price,
               sell_price,
               profit_loss,
               code,
               accumulative_profit_loss,
               buy_ma5,
               sell_ma5)
            values
              (v_temp_buy_time,
               v_temp_sell_time,
               v_temp_buy_price,
               v_temp_sell_price,
               v_temp_profit_loss,
               v_temp_code,
               v_init_last_acc_profit_loss,
               v_temp_buy_ma5,
               v_temp_sell_ma5);
          
            v_start_track_gold_cross_stage := 0;
          else
            continue;
          end if;
        end if;
      end loop;
    end loop;
    commit;
  end CAL_MDL_CF_HOUR_CP_MA_GC_INCR;

  /*---------------------------------- 海量地向表MDL_C_F_HOUR_C_P_MA_D_C中插入数据 --------------------------------------*/
  procedure CAL_MDL_CF_HOUR_CP_MA_DC as
    -- 表示CODE
    v_code varchar2(100);
    -- 作为临时变量，表示CODE,BUY_TIME,SELL_TIME,BUY_PRICE,SELL_PRICE,BUY_MA5,SELL_MA5
    v_temp_code       varchar2(100);
    v_temp_buy_time   date;
    v_temp_sell_time  date;
    v_temp_buy_price  number;
    v_temp_sell_price number;
    v_temp_buy_ma5    number;
    v_temp_sell_ma5   number;
    -- 1表示close_price>ma5的阶段，2表示close_price<=ma5的阶段
    v_start_track_dead_cross_stage number;
    -- 每只期货初始的accumulative_profit_loss值为100（表示百分之一百），之后代表上一次交易的累计盈亏百分比
    v_init_last_acc_profit_loss number;
    -- 表示字段PROFIT_LOSS的临时变量
    v_temp_profit_loss number;
    -- 用于获取所有的CODE
    cursor cur_all_code is
      select distinct t.code from commodity_future_hour_data t;
    -- 用于根据CODE获取某一只期货的所有交易记录
    cursor cur_single is
      select *
        from commodity_future_hour_data t
       where t.code = v_code
       order by t.end_time asc;
  begin
    for i in cur_all_code loop
      v_code                         := i.code;
      v_init_last_acc_profit_loss    := 100;
      v_start_track_dead_cross_stage := 0;
    
      for j in cur_single loop
        if j.close_price < j.ma5 then
          if v_start_track_dead_cross_stage = 0 then
            -- 卖出
            v_temp_code                    := j.code;
            v_temp_sell_time               := j.end_time;
            v_temp_sell_price              := j.close_price;
            v_temp_sell_ma5                := j.ma5;
            v_start_track_dead_cross_stage := 1;
          else
            continue;
          end if;
        end if;
      
        if j.close_price >= j.ma5 then
          if v_start_track_dead_cross_stage = 1 then
            -- 买入
            v_temp_buy_time             := j.end_time;
            v_temp_buy_price            := j.close_price;
            v_temp_buy_ma5              := j.ma5;
            v_temp_profit_loss          := round((v_temp_sell_price -
                                                 v_temp_buy_price) /
                                                 v_temp_sell_price,
                                                 4) * 100;
            v_init_last_acc_profit_loss := v_init_last_acc_profit_loss *
                                           (1 + v_temp_profit_loss / 100);
            -- 插入记录
            insert into mdl_c_f_hour_c_p_ma5_d_c
              (buy_time,
               sell_time,
               buy_price,
               sell_price,
               profit_loss,
               code,
               accumulative_profit_loss,
               buy_ma5,
               sell_ma5)
            values
              (v_temp_buy_time,
               v_temp_sell_time,
               v_temp_buy_price,
               v_temp_sell_price,
               v_temp_profit_loss,
               v_temp_code,
               v_init_last_acc_profit_loss,
               v_temp_buy_ma5,
               v_temp_sell_ma5);
          
            -- 重置为0，表示还没有买入
            v_start_track_dead_cross_stage := 0;
          else
            continue;
          end if;
        end if;
      end loop;
    end loop;
    commit;
  end CAL_MDL_CF_HOUR_CP_MA_DC;

  /*---------------------------------- 增量地向表MDL_C_F_HOUR_C_P_MA_D_C中插入数据 ------------------------------------*/
  procedure CAL_MDL_CF_HOUR_CP_MA_DC_INCR(p_end_date in varchar2) as
    -- 表示CODE
    v_code varchar2(100);
    -- 作为临时变量，表示CODE,BUY_TIME,SELL_TIME,BUY_PRICE,SELL_PRICE,BUY_MA5,SELL_MA5
    v_temp_code       varchar2(100);
    v_temp_buy_time   date;
    v_temp_sell_time  date;
    v_temp_buy_price  number;
    v_temp_sell_price number;
    v_temp_buy_ma5    number;
    v_temp_sell_ma5   number;
    -- 1表示close_price>ma5的阶段，0表示close_price<=ma5的阶段
    v_start_track_dead_cross_stage number;
    -- 每只期货初始的accumulative_profit_loss值为100（表示百分之一百），之后代表上一次交易的累计盈亏百分比
    v_init_last_acc_profit_loss number;
    -- 表示字段PROFIT_LOSS的临时变量
    v_temp_profit_loss number;
    -- 用于获取所有的CODE
    cursor cur_all_code is
      select distinct t.code from commodity_future_hour_data t;
    -- 从某一只期货在mdl_c_f_hour_c_p_ma5_d_c表中最后的买出日期，到参数p_end_date之间的交易记录，
    -- 并按升序排列。这段时间内可能存在先是close_price死叉ma5，然后close_price金叉ma5。
    -- buy_time和sell_time效果一样
    cursor cur_c_p_gold_dead_cross_ma5 is
      select *
        from commodity_future_hour_data t
       where t.code = v_code
         and t.end_time >
             (select max(mdfdcpmdc.buy_time)
                from mdl_c_f_hour_c_p_ma5_d_c mdfdcpmdc
               where mdfdcpmdc.code = v_code)
         and t.end_time <= to_date(p_end_date, 'yyyy-mm-dd')
       order by t.end_time asc;
  begin
    for i in cur_all_code loop
      v_code                         := i.code;
      v_start_track_dead_cross_stage := 0;
      -- 查找最近的accumulative_profit_loss
      begin
        select b.accumulative_profit_loss
          into v_init_last_acc_profit_loss
          from (select *
                  from mdl_c_f_hour_c_p_ma5_d_c t
                 where t.code = v_code
                 order by t.buy_time desc) b
         where rownum <= 1;
      exception
        when no_data_found then
          dbms_output.put_line('code为【' || v_code || '】，
                                                            在mdl_c_f_hour_c_p_ma5_d_c表中没有记录');
      end;
    
      for j in cur_c_p_gold_dead_cross_ma5 loop
        if j.close_price < j.ma5 then
          -- 买入
          if v_start_track_dead_cross_stage = 0 then
            v_temp_code                    := j.code;
            v_temp_sell_time               := j.end_time;
            v_temp_sell_price              := j.close_price;
            v_temp_sell_ma5                := j.ma5;
            v_start_track_dead_cross_stage := 1;
          else
            continue;
          end if;
        end if;
      
        if j.close_price >= j.ma5 then
          -- 卖出
          if v_start_track_dead_cross_stage = 1 then
            v_temp_buy_time  := j.end_time;
            v_temp_buy_price := j.close_price;
            v_temp_buy_ma5   := j.ma5;
          
            v_temp_profit_loss          := round((v_temp_sell_price -
                                                 v_temp_buy_price) /
                                                 v_temp_sell_price,
                                                 4) * 100;
            v_init_last_acc_profit_loss := v_init_last_acc_profit_loss *
                                           (1 + v_temp_profit_loss / 100);
          
            insert into mdl_c_f_hour_c_p_ma5_d_c
              (buy_time,
               sell_time,
               buy_price,
               sell_price,
               profit_loss,
               code,
               accumulative_profit_loss,
               buy_ma5,
               sell_ma5)
            values
              (v_temp_buy_time,
               v_temp_sell_time,
               v_temp_buy_price,
               v_temp_sell_price,
               v_temp_profit_loss,
               v_temp_code,
               v_init_last_acc_profit_loss,
               v_temp_buy_ma5,
               v_temp_sell_ma5);
          
            v_start_track_dead_cross_stage := 0;
          else
            continue;
          end if;
        end if;
      end loop;
    end loop;
    commit;
  end CAL_MDL_CF_HOUR_CP_MA_DC_INCR;

  /*---------------------------------- 海量地向表MDL_C_F_HOUR_HEI_KIN_ASHI_UP中插入数据 --------------------------------------*/
  procedure CAL_MDL_C_F_HOUR_HKA_UP as
    -- 表示CODE
    v_code varchar2(100);
    -- 作为临时变量，表示CODE,BUY_TIME,SELL_TIME,BUY_PRICE,SELL_PRICE
    v_temp_code       varchar2(100);
    v_temp_buy_time   date;
    v_temp_sell_time  date;
    v_temp_buy_price  number;
    v_temp_sell_price number;
    -- 如果为1，则表示已经买入期货了；如果为0，则表示还没有买入期货
    v_start_track_h_k_a_stage number;
    -- 每只期货初始的accumulative_profit_loss值为100（表示百分之一百），之后代表上一次交易的累计盈亏百分比
    v_init_last_acc_profit_loss number;
    -- 表示字段PROFIT_LOSS的临时变量
    v_temp_profit_loss number;
    -- 用于获取所有的CODE
    cursor cur_all_code is
      select distinct t.code from commodity_future_hour_data t;
    -- 用于根据CODE获取某一只期货的所有交易记录
    cursor cur_single is
      select *
        from commodity_future_hour_data t
       where t.code = v_code
       order by t.end_time asc;
  begin
    for i in cur_all_code loop
      v_code                      := i.code;
      v_init_last_acc_profit_loss := 100;
      v_start_track_h_k_a_stage   := 0;
    
      for j in cur_single loop
      
        if j.ha_close_price <= j.ha_open_price then
          -- 卖出
          if v_start_track_h_k_a_stage = 1 then
            v_start_track_h_k_a_stage   := 0;
            v_temp_sell_time            := j.end_time;
            v_temp_sell_price           := j.close_price;
            v_temp_profit_loss          := round((v_temp_sell_price -
                                                 v_temp_buy_price) /
                                                 v_temp_buy_price,
                                                 4) * 100;
            v_init_last_acc_profit_loss := v_init_last_acc_profit_loss *
                                           (1 + v_temp_profit_loss / 100);
          
            -- 插入记录
            insert into mdl_c_f_hour_hei_kin_ashi_up
              (code,
               sell_time,
               sell_price,
               buy_time,
               buy_price,
               accumulative_profit_loss,
               profit_loss)
            values
              (v_temp_code,
               v_temp_sell_time,
               v_temp_sell_price,
               v_temp_buy_time,
               v_temp_buy_price,
               v_init_last_acc_profit_loss,
               v_temp_profit_loss);
          else
            continue;
          end if;
        end if;
      
        if j.ha_close_price > j.ha_open_price then
          -- 买入
          if v_start_track_h_k_a_stage != 1 then
            v_start_track_h_k_a_stage := 1;
            v_temp_buy_time           := j.end_time;
            v_temp_buy_price          := j.close_price;
            v_temp_code               := j.code;
          end if;
        end if;
      end loop;
    end loop;
    commit;
  end CAL_MDL_C_F_HOUR_HKA_UP;

  /*---------------------------------- 增量地向表MDL_C_F_HOUR_HEI_KIN_ASHI_UP中插入数据 ------------------------------------*/
  procedure CAL_MDL_C_F_HOUR_HKA_UP_INCR(p_end_date in varchar2) as
    -- 表示CODE
    v_code varchar2(100);
    -- 作为临时变量，表示CODE,BUY_TIME,SELL_TIME,BUY_PRICE,SELL_PRICE
    v_temp_code       varchar2(100);
    v_temp_buy_time   date;
    v_temp_sell_time  date;
    v_temp_buy_price  number;
    v_temp_sell_price number;
    -- 每只期货初始的accumulative_profit_loss值为100（表示百分之一百），之后代表上一次交易的累计盈亏百分比
    v_init_last_acc_profit_loss number;
    -- 表示字段PROFIT_LOSS的临时变量
    v_temp_profit_loss number;
    -- 1表示ha_close_price阳线的阶段，0表示ha_close_price阴线的阶段
    v_start_track_gold_cross_stage number;
    -- 用于获取所有的CODE
    cursor cur_all_code is
      select distinct t.code from commodity_future_hour_data t;
    -- 从某一只期货在mdl_hei_kin_ashi_up_down表中最后的卖出日期，到参数p_end_date之间的交易记录，
    -- 并按升序排列。这段时间内可能存在先是ha_close_price阳线，然后ha_close_price阴线。
    -- buy_time和sell_time效果一样
    cursor cur_hei_kin_ashi_up is
      select *
        from commodity_future_hour_data t
       where t.code = v_code
         and t.end_time >
             (select max(mcfdhkau.sell_time)
                from mdl_c_f_hour_hei_kin_ashi_up mcfdhkau
               where mcfdhkau.code = v_code)
         and t.end_time <= to_date(p_end_date, 'yyyy-mm-dd')
       order by t.end_time asc;
  begin
    for i in cur_all_code loop
      v_code                         := i.code;
      v_start_track_gold_cross_stage := 0;
    
      -- 查找最近的accumulative_profit_loss
      begin
        select b.accumulative_profit_loss
          into v_init_last_acc_profit_loss
          from (select *
                  from mdl_c_f_hour_hei_kin_ashi_up t
                 where t.code = v_code
                 order by t.sell_time desc) b
         where rownum <= 1;
      exception
        when no_data_found then
          dbms_output.put_line('code为【' || v_code || '】，
                                                            在mdl_c_f_hour_hei_kin_ashi_up表中没有记录');
      end;
    
      for j in cur_hei_kin_ashi_up loop
        if j.ha_close_price > j.ha_open_price then
          -- 买入
          if v_start_track_gold_cross_stage = 0 then
            v_temp_code                    := j.code;
            v_temp_buy_time                := j.end_time;
            v_temp_buy_price               := j.close_price;
            v_start_track_gold_cross_stage := 1;
          else
            continue;
          end if;
        end if;
      
        if j.ha_close_price <= j.ha_open_price then
          -- 卖出
          if v_start_track_gold_cross_stage = 1 then
            v_temp_sell_time  := j.end_time;
            v_temp_sell_price := j.close_price;
          
            v_temp_profit_loss          := round((v_temp_sell_price -
                                                 v_temp_buy_price) /
                                                 v_temp_buy_price,
                                                 4) * 100;
            v_init_last_acc_profit_loss := v_init_last_acc_profit_loss *
                                           (1 + v_temp_profit_loss / 100);
          
            insert into mdl_c_f_hour_hei_kin_ashi_up
              (buy_time,
               sell_time,
               buy_price,
               sell_price,
               profit_loss,
               code,
               accumulative_profit_loss)
            values
              (v_temp_buy_time,
               v_temp_sell_time,
               v_temp_buy_price,
               v_temp_sell_price,
               v_temp_profit_loss,
               v_temp_code,
               v_init_last_acc_profit_loss);
          
            v_start_track_gold_cross_stage := 0;
          else
            continue;
          end if;
        end if;
      end loop;
    end loop;
    commit;
  end CAL_MDL_C_F_HOUR_HKA_UP_INCR;

  /*---------------------------------- 海量地向表MDL_C_F_HOUR_HEI_KIN_ASHI_DOWN中插入数据 --------------------------------------*/
  procedure CAL_MDL_C_F_HOUR_HKA_DOWN as
    -- 表示CODE
    v_code varchar2(100);
    -- 作为临时变量，表示CODE,BUY_TIME,SELL_TIME,BUY_PRICE,SELL_PRICE
    v_temp_code       varchar2(100);
    v_temp_buy_time   date;
    v_temp_sell_time  date;
    v_temp_buy_price  number;
    v_temp_sell_price number;
    -- 如果为1，则表示已经买入期货了；如果为0，则表示还没有买入期货
    v_start_track_h_k_a_stage number;
    -- 每只期货初始的accumulative_profit_loss值为100（表示百分之一百），之后代表上一次交易的累计盈亏百分比
    v_init_last_acc_profit_loss number;
    -- 表示字段PROFIT_LOSS的临时变量
    v_temp_profit_loss number;
    -- 用于获取所有的CODE
    cursor cur_all_code is
      select distinct t.code from commodity_future_hour_data t;
    -- 用于根据CODE_获取某一只期货的所有交易记录
    cursor cur_single is
      select *
        from commodity_future_hour_data t
       where t.code = v_code
       order by t.end_time asc;
  begin
    for i in cur_all_code loop
      v_code                      := i.code;
      v_init_last_acc_profit_loss := 100;
      v_start_track_h_k_a_stage   := 0;
    
      for j in cur_single loop
      
        if j.ha_close_price >= j.ha_open_price then
          -- 买入
          if v_start_track_h_k_a_stage = 1 then
            v_start_track_h_k_a_stage   := 0;
            v_temp_buy_time             := j.end_time;
            v_temp_buy_price            := j.close_price;
            v_temp_profit_loss          := round((v_temp_sell_price -
                                                 v_temp_buy_price) /
                                                 v_temp_sell_price,
                                                 4) * 100;
            v_init_last_acc_profit_loss := v_init_last_acc_profit_loss *
                                           (1 + v_temp_profit_loss / 100);
          
            -- 插入记录
            insert into mdl_c_f_hour_hei_kin_ashi_down
              (code,
               sell_time,
               sell_price,
               buy_time,
               buy_price,
               accumulative_profit_loss,
               profit_loss)
            values
              (v_temp_code,
               v_temp_sell_time,
               v_temp_sell_price,
               v_temp_buy_time,
               v_temp_buy_price,
               v_init_last_acc_profit_loss,
               v_temp_profit_loss);
          else
            continue;
          end if;
        end if;
      
        if j.ha_close_price < j.ha_open_price then
          -- 卖出
          if v_start_track_h_k_a_stage != 1 then
            v_start_track_h_k_a_stage := 1;
            v_temp_sell_time          := j.end_time;
            v_temp_sell_price         := j.close_price;
            v_temp_code               := j.code;
          end if;
        end if;
      end loop;
    end loop;
    commit;
  end CAL_MDL_C_F_HOUR_HKA_DOWN;

  /*---------------------------------- 增量地向表MDL_C_F_HOUR_HEI_KIN_ASHI_DOWN中插入数据 ------------------------------------*/
  procedure CAL_MDL_C_F_HOUR_HKA_DOWN_INCR(p_end_date in varchar2) as
    -- 表示CODE
    v_code varchar2(100);
    -- 作为临时变量，表示CODE,BUY_TIME,SELL_TIME,BUY_PRICE,SELL_PRICE
    v_temp_code       varchar2(100);
    v_temp_buy_time   date;
    v_temp_sell_time  date;
    v_temp_buy_price  number;
    v_temp_sell_price number;
    -- 每只期货初始的accumulative_profit_loss值为100（表示百分之一百），之后代表上一次交易的累计盈亏百分比
    v_init_last_acc_profit_loss number;
    -- 表示字段PROFIT_LOSS的临时变量
    v_temp_profit_loss number;
    -- 1表示ha_close_price阳线的阶段，0表示ha_close_price阴线的阶段
    v_start_track_dead_cross_stage number;
    -- 用于获取所有的CODE
    cursor cur_all_code is
      select distinct t.code from commodity_future_hour_data t;
    -- 从某一只期货在mdl_c_f_hour_hei_kin_ashi_down表中最后的买入日期，到参数p_end_date之间的交易记录，
    -- 并按升序排列。这段时间内可能存在先是ha_close_price阴线，然后ha_close_price阳线。
    -- buy_time和sell_time效果一样
    cursor cur_hei_kin_ashi_down is
      select *
        from commodity_future_hour_data t
       where t.code = v_code
         and t.end_time >
             (select max(mcfdhkad.buy_time)
                from mdl_c_f_hour_hei_kin_ashi_down mcfdhkad
               where mcfdhkad.code = v_code)
         and t.end_time <= to_date(p_end_date, 'yyyy-mm-dd')
       order by t.end_time asc;
  begin
    for i in cur_all_code loop
      v_code                         := i.code;
      v_start_track_dead_cross_stage := 0;
    
      -- 查找最近的accumulative_profit_loss
      begin
        select b.accumulative_profit_loss
          into v_init_last_acc_profit_loss
          from (select *
                  from mdl_c_f_hour_hei_kin_ashi_down t
                 where t.code = v_code
                 order by t.buy_time desc) b
         where rownum <= 1;
      exception
        when no_data_found then
          dbms_output.put_line('code为【' || v_code || '】，
                                                            在mdl_c_f_hour_hei_kin_ashi_down表中没有记录');
      end;
    
      for j in cur_hei_kin_ashi_down loop
        if j.ha_close_price < j.ha_open_price then
          -- 卖出
          if v_start_track_dead_cross_stage = 0 then
            v_temp_code                    := j.code;
            v_temp_sell_time               := j.end_time;
            v_temp_sell_price              := j.close_price;
            v_start_track_dead_cross_stage := 1;
          else
            continue;
          end if;
        end if;
      
        if j.ha_close_price >= j.ha_open_price then
          -- 买入
          if v_start_track_dead_cross_stage = 1 then
            v_temp_buy_time  := j.end_time;
            v_temp_buy_price := j.close_price;
          
            v_temp_profit_loss          := round((v_temp_sell_price -
                                                 v_temp_buy_price) /
                                                 v_temp_sell_price,
                                                 4) * 100;
            v_init_last_acc_profit_loss := v_init_last_acc_profit_loss *
                                           (1 + v_temp_profit_loss / 100);
          
            insert into mdl_c_f_hour_hei_kin_ashi_down
              (buy_time,
               sell_time,
               buy_price,
               sell_price,
               profit_loss,
               code,
               accumulative_profit_loss)
            values
              (v_temp_buy_time,
               v_temp_sell_time,
               v_temp_buy_price,
               v_temp_sell_price,
               v_temp_profit_loss,
               v_temp_code,
               v_init_last_acc_profit_loss);
          
            v_start_track_dead_cross_stage := 0;
          else
            continue;
          end if;
        end if;
      end loop;
    end loop;
    commit;
  end CAL_MDL_C_F_HOUR_HKA_DOWN_INCR;

  /*---------------------------------- 海量地向表MDL_C_F_KD_GOLD_CROSS中插入数据 --------------------------------------*/
  procedure CAL_MDL_C_F_KD_GOLD_CROSS as
    -- 表示CODE
    v_code varchar2(100);
    -- 作为临时变量，表示CODE,BUY_TIME,SELL_TIME,BUY_PRICE,SELL_PRICE,K,D
    v_temp_code       varchar2(100);
    v_temp_buy_time   date;
    v_temp_sell_time  date;
    v_temp_buy_price  number;
    v_temp_sell_price number;
    v_temp_buy_k      number;
    v_temp_sell_k     number;
    v_temp_buy_d      number;
    v_temp_sell_d     number;
    -- 如果为1，则表示已经买入期货了；如果为0，则表示还没有买入期货
    v_start_track_kd_g_c_stage number;
    -- 每只期货初始的accumulative_profit_loss值为100（表示百分之一百），之后代表上一次交易的累计盈亏百分比
    v_init_last_acc_profit_loss number;
    -- 表示字段PROFIT_LOSS的临时变量
    v_temp_profit_loss number;
    -- 用于获取所有的CODE
    cursor cur_all_code is
      select distinct t.code from commodity_future_hour_data t;
    -- 用于根据CODE获取某一只期货的所有交易记录
    cursor cur_single is
      select *
        from commodity_future_hour_data t
       where t.code = v_code
       order by t.end_time asc;
  begin
    for i in cur_all_code loop
      v_code                      := i.code;
      v_init_last_acc_profit_loss := 100;
      v_start_track_kd_g_c_stage  := 0;
    
      for j in cur_single loop
      
        if j.k <= j.d then
          -- 卖出
          if v_start_track_kd_g_c_stage = 1 then
            v_start_track_kd_g_c_stage  := 0;
            v_temp_sell_time            := j.end_time;
            v_temp_sell_price           := j.close_price;
            v_temp_sell_k               := j.k;
            v_temp_sell_d               := j.d;
            v_temp_profit_loss          := round((v_temp_sell_price -
                                                 v_temp_buy_price) /
                                                 v_temp_buy_price,
                                                 4) * 100;
            v_init_last_acc_profit_loss := v_init_last_acc_profit_loss *
                                           (1 + v_temp_profit_loss / 100);
          
            -- 插入记录
            insert into mdl_c_f_hour_kd_gold_cross
              (code,
               sell_time,
               sell_price,
               sell_k,
               sell_d,
               buy_time,
               buy_price,
               buy_k,
               buy_d,
               accumulative_profit_loss,
               profit_loss)
            values
              (v_temp_code,
               v_temp_sell_time,
               v_temp_sell_price,
               v_temp_sell_k,
               v_temp_sell_d,
               v_temp_buy_time,
               v_temp_buy_price,
               v_temp_buy_k,
               v_temp_buy_d,
               v_init_last_acc_profit_loss,
               v_temp_profit_loss);
          else
            continue;
          end if;
        end if;
      
        if j.k > j.d then
          -- 买入
          if v_start_track_kd_g_c_stage != 1 then
            v_start_track_kd_g_c_stage := 1;
            v_temp_buy_time            := j.end_time;
            v_temp_buy_price           := j.close_price;
            v_temp_buy_k               := j.k;
            v_temp_buy_d               := j.d;
            v_temp_code                := j.code;
          end if;
        end if;
      end loop;
    end loop;
    commit;
  end CAL_MDL_C_F_KD_GOLD_CROSS;

  /*---------------------------------- 增量地向表MDL_C_F_KD_GOLD_CROSS中插入数据 ------------------------------------*/
  procedure CAL_MDL_C_F_KD_GOLD_CROSS_INCR(p_end_date in varchar2) as
    -- 表示CODE
    v_code varchar2(100);
    -- 表示DATE
    v_date date;
    -- 表示两小时记录中的第一小时，用于判断KD是否发生了金叉或死叉
    v_first commodity_future_hour_data%rowtype;
    -- 表示两小时记录中的第二小时，用于判断KD是否发生了金叉或死叉
    v_second commodity_future_hour_data%rowtype;
    -- 作为临时变量，表示CODE,BUY_TIME,SELL_TIME,BUY_PRICE,SELL_PRICE,BUY_K,BUY_D,SELL_K,SELL_D
    v_temp_code       varchar2(100);
    v_temp_buy_time   date;
    v_temp_sell_time  date;
    v_temp_buy_price  number;
    v_temp_sell_price number;
    v_temp_buy_k      number;
    v_temp_buy_d      number;
    v_temp_sell_k     number;
    v_temp_sell_d     number;
    -- 用来判断现在是否是k>d的阶段，从而可以判断死叉
    v_start_track_gold_cross_stage number;
    -- 用来表示金叉和死叉是否发现了
    v_gold_cross_found  number := 0;
    v_death_cross_found number := 0;
    -- 每只期货初始的accumulative_profit_loss值为100（表示百分之一百），之后代表上一次交易的累计盈亏百分比
    v_init_last_acc_profit_loss number;
    -- 表示字段PROFIT_LOSS的临时变量
    v_temp_profit_loss number;
    -- 用于获取所有的CODE
    cursor cur_all_code is
      select distinct t.code from commodity_future_hour_data t;
    -- 用于根据CODE获取某一只期货的所有交易记录。
    -- 1997-01-01是commodity_future_hour_data表中最早的交易记录。
    cursor cur_single is
      select *
        from commodity_future_hour_data t1
       where t1.end_time >
             (select nvl(max(t.sell_time),
                         to_date('1997-01-01', 'yyyy-mm-dd'))
                from mdl_c_f_hour_kd_gold_cross t
               where t.code = v_code)
         and t1.end_time <= to_date(p_end_date, 'yyyy-mm-dd')
         and t1.code = v_code
       order by t1.end_time asc;
    -- 用于获取某一只期货两小时的交易记录，用于判断MACD是否发生了金叉或死叉
    cursor cur_single_two_record is
      select *
        from (select *
                from commodity_future_hour_data t
               where t.end_time >= v_date
                 and t.code = v_code
               order by t.end_time asc)
       where rownum <= 2;
  begin
    for i in cur_all_code loop
      v_code                         := i.code;
      v_init_last_acc_profit_loss    := 100;
      v_start_track_gold_cross_stage := 0;
      for j in cur_single loop
        v_date := j.end_time;
        -- 如果最早的数据是k>d，那么接下来只有可能先出现死叉，所以要判断：j.k<j.d，也就是说如果第一段数据是k>d，则将其忽略
        -- 之后在确认了金叉后，需要确认死叉，所以引入了表示变量v_start_track_gold_cross_stage，当其为1时，表示接下来只可能出现死叉
        if j.k < j.d or (j.k > j.d and v_start_track_gold_cross_stage = 1) then
          -- 分别将两小时的记录赋给相应的变量
          for x in cur_single_two_record loop
            if cur_single_two_record%rowcount = 1 then
              v_first := x;
            elsif cur_single_two_record%rowcount = 2 then
              v_second := x;
            end if;
          end loop;
          -- 如果出现了金叉，给临时变量赋值
          if v_first.k < v_first.d and v_second.k > v_second.d and
             v_start_track_gold_cross_stage = 0 then
            v_temp_code        := v_second.code;
            v_temp_buy_time    := v_second.end_time;
            v_temp_buy_price   := v_second.close_price;
            v_temp_buy_k       := v_second.k;
            v_temp_buy_d       := v_second.d;
            v_gold_cross_found := 1;
            -- 当金叉发生后，只可能发生死叉，因此要将v_start_track_gold_cross_stage设置为1
            v_start_track_gold_cross_stage := 1;
          
          end if;
          -- 如果出现了死叉，给临时变量赋值
          if v_first.k > v_first.d and v_second.k < v_second.d and
             v_start_track_gold_cross_stage = 1 then
            v_temp_sell_time    := v_second.end_time;
            v_temp_sell_price   := v_second.close_price;
            v_temp_sell_k       := v_second.k;
            v_temp_sell_d       := v_second.d;
            v_death_cross_found := 1;
            -- 当死叉发生后，只可能发生金叉，因此要将v_start_track_gold_cross_stage设置为0
            v_start_track_gold_cross_stage := 0;
          
          end if;
          -- 插入数据
          if v_gold_cross_found = 1 and v_death_cross_found = 1 and
             v_temp_buy_time is not null and v_temp_sell_time is not null and
             v_temp_code is not null then
            v_temp_profit_loss := round((v_temp_sell_price -
                                        v_temp_buy_price) /
                                        v_temp_buy_price,
                                        4) * 100;
            -- 获取最近一次交易后的accumulative_profit_loss
            begin
              select t.accumulative_profit_loss
                into v_init_last_acc_profit_loss
                from (select *
                        from mdl_c_f_hour_kd_gold_cross t
                       where t.code = v_code
                       order by t.sell_time desc) t
               where rownum <= 1;
            exception
              when no_data_found then
                dbms_output.put_line('code为【' || v_code || '】，
                                                            在mdl_c_f_hour_kd_gold_cross表中没有记录');
            end;
            -- 计算本次交易后的accumulative_profit_loss
            v_init_last_acc_profit_loss := v_init_last_acc_profit_loss *
                                           (1 + v_temp_profit_loss / 100);
          
            insert into MDL_C_F_HOUR_KD_GOLD_CROSS
              (buy_time,
               sell_time,
               buy_price,
               sell_price,
               profit_loss,
               code,
               accumulative_profit_loss,
               buy_k,
               buy_d,
               sell_k,
               sell_d)
            values
              (v_temp_buy_time,
               v_temp_sell_time,
               v_temp_buy_price,
               v_temp_sell_price,
               v_temp_profit_loss,
               v_temp_code,
               v_init_last_acc_profit_loss,
               v_temp_buy_k,
               v_temp_buy_d,
               v_temp_sell_k,
               v_temp_sell_d);
            commit;
          
            v_gold_cross_found  := 0;
            v_death_cross_found := 0;
          end if;
        end if;
      end loop;
    end loop;
  end CAL_MDL_C_F_KD_GOLD_CROSS_INCR;

  /*---------------------------------- 海量地向表MDL_C_F_KD_DEAD_CROSS中插入数据 --------------------------------------*/
  procedure CAL_MDL_C_F_KD_DEAD_CROSS as
    -- 表示CODE
    v_code varchar2(100);
    -- 作为临时变量，表示CODE,BUY_TIME,SELL_TIME,BUY_PRICE,SELL_PRICE,K,D
    v_temp_code       varchar2(100);
    v_temp_buy_time   date;
    v_temp_sell_time  date;
    v_temp_buy_price  number;
    v_temp_sell_price number;
    v_temp_buy_k      number;
    v_temp_sell_k     number;
    v_temp_buy_d      number;
    v_temp_sell_d     number;
    -- 如果为1，则表示已经买入期货了；如果为0，则表示还没有买入期货
    v_start_track_kd_d_c_stage number;
    -- 每只期货初始的accumulative_profit_loss值为100（表示百分之一百），之后代表上一次交易的累计盈亏百分比
    v_init_last_acc_profit_loss number;
    -- 表示字段PROFIT_LOSS的临时变量
    v_temp_profit_loss number;
    -- 用于获取所有的CODE
    cursor cur_all_code is
      select distinct t.code from commodity_future_hour_data t;
    -- 用于根据CODE获取某一只期货的所有交易记录
    cursor cur_single is
      select *
        from commodity_future_hour_data t
       where t.code = v_code
       order by t.end_time asc;
  begin
    for i in cur_all_code loop
      v_code                      := i.code;
      v_init_last_acc_profit_loss := 100;
      v_start_track_kd_d_c_stage  := 0;
    
      for j in cur_single loop
      
        if j.k >= j.d then
          -- 买入
          if v_start_track_kd_d_c_stage = 1 then
            v_start_track_kd_d_c_stage  := 0;
            v_temp_buy_time             := j.end_time;
            v_temp_buy_price            := j.close_price;
            v_temp_buy_k                := j.k;
            v_temp_buy_d                := j.d;
            v_temp_profit_loss          := round((v_temp_sell_price -
                                                 v_temp_buy_price) /
                                                 v_temp_sell_price,
                                                 4) * 100;
            v_init_last_acc_profit_loss := v_init_last_acc_profit_loss *
                                           (1 + v_temp_profit_loss / 100);
          
            -- 插入记录
            insert into mdl_c_f_hour_kd_dead_cross
              (code,
               sell_time,
               sell_price,
               sell_k,
               sell_d,
               buy_time,
               buy_price,
               buy_k,
               buy_d,
               accumulative_profit_loss,
               profit_loss)
            values
              (v_temp_code,
               v_temp_sell_time,
               v_temp_sell_price,
               v_temp_sell_k,
               v_temp_sell_d,
               v_temp_buy_time,
               v_temp_buy_price,
               v_temp_buy_k,
               v_temp_buy_d,
               v_init_last_acc_profit_loss,
               v_temp_profit_loss);
          else
            continue;
          end if;
        end if;
      
        if j.k < j.d then
          -- 卖出
          if v_start_track_kd_d_c_stage != 1 then
            v_start_track_kd_d_c_stage := 1;
            v_temp_sell_time           := j.end_time;
            v_temp_sell_price          := j.close_price;
            v_temp_sell_k              := j.k;
            v_temp_sell_d              := j.d;
            v_temp_code                := j.code;
          end if;
        end if;
      end loop;
    end loop;
    commit;
  end CAL_MDL_C_F_KD_DEAD_CROSS;

  /*---------------------------------- 增量地向表MDL_C_F_KD_DEAD_CROSS中插入数据 ------------------------------------*/
  procedure CAL_MDL_C_F_KD_DEAD_CROSS_INCR(p_end_date in varchar2) as
    -- 表示CODE
    v_code varchar2(100);
    -- 表示DATE
    v_date date;
    -- 表示两小时记录中的第一小时，用于判断KD是否发生了金叉或死叉
    v_first commodity_future_hour_data%rowtype;
    -- 表示两小时记录中的第二小时，用于判断KD是否发生了金叉或死叉
    v_second commodity_future_hour_data%rowtype;
    -- 作为临时变量，表示CODE,BUY_TIME,SELL_TIME,BUY_PRICE,SELL_PRICE,BUY_K,BUY_D,SELL_K,SELL_D
    v_temp_code       varchar2(100);
    v_temp_buy_time   date;
    v_temp_sell_time  date;
    v_temp_buy_price  number;
    v_temp_sell_price number;
    v_temp_buy_k      number;
    v_temp_buy_d      number;
    v_temp_sell_k     number;
    v_temp_sell_d     number;
    -- 用来判断现在是否是k<d的阶段，从而可以判断死叉
    v_start_track_dead_cross_stage number;
    -- 用来表示金叉和死叉是否发现了
    v_gold_cross_found number := 0;
    v_dead_cross_found number := 0;
    -- 每只期货初始的accumulative_profit_loss值为100（表示百分之一百），之后代表上一次交易的累计盈亏百分比
    v_init_last_acc_profit_loss number;
    -- 表示字段PROFIT_LOSS的临时变量
    v_temp_profit_loss number;
    -- 用于获取所有的CODE
    cursor cur_all_code is
      select distinct t.code from commodity_future_hour_data t;
    -- 用于根据CODE获取某一只期货的所有交易记录。
    -- 1997-01-01是commodity_future_hour_data表中最早的交易记录。
    cursor cur_single is
      select *
        from commodity_future_hour_data t1
       where t1.end_time >
             (select nvl(max(t.buy_time),
                         to_date('1997-01-01', 'yyyy-mm-dd'))
                from mdl_c_f_hour_kd_dead_cross t
               where t.code = v_code)
         and t1.end_time <= to_date(p_end_date, 'yyyy-mm-dd')
         and t1.code = v_code
       order by t1.end_time asc;
    -- 用于获取某一只期货两小时的交易记录，用于判断MACD是否发生了金叉或死叉
    cursor cur_single_two_record is
      select *
        from (select *
                from commodity_future_hour_data t
               where t.end_time >= v_date
                 and t.code = v_code
               order by t.end_time asc)
       where rownum <= 2;
  begin
    for i in cur_all_code loop
      v_code                         := i.code;
      v_init_last_acc_profit_loss    := 100;
      v_start_track_dead_cross_stage := 0;
      for j in cur_single loop
        v_date := j.end_time;
        -- 如果最早的数据是k<d，那么接下来只有可能先出现金叉，所以要判断：j.k>j.d，也就是说如果第一段数据是k<d，则将其忽略
        -- 之后在确认了死叉后，需要确认金叉，所以引入了表示变量v_start_track_dead_cross_stage，当其为1时，表示接下来只可能出现金叉
        if j.k > j.d or (j.k < j.d and v_start_track_dead_cross_stage = 1) then
          -- 分别将两小时的记录赋给相应的变量
          for x in cur_single_two_record loop
            if cur_single_two_record%rowcount = 1 then
              v_first := x;
            elsif cur_single_two_record%rowcount = 2 then
              v_second := x;
            end if;
          end loop;
          -- 如果出现了死叉，给临时变量赋值
          if v_first.k > v_first.d and v_second.k < v_second.d and
             v_start_track_dead_cross_stage = 0 then
            v_temp_code        := v_second.code;
            v_temp_sell_time   := v_second.end_time;
            v_temp_sell_price  := v_second.close_price;
            v_temp_sell_k      := v_second.k;
            v_temp_sell_d      := v_second.d;
            v_gold_cross_found := 1;
            -- 当死叉发生后，只可能发生金叉，因此要将v_start_track_dead_cross_stage设置为1
            v_start_track_dead_cross_stage := 1;
          
          end if;
          -- 如果出现了金叉，给临时变量赋值
          if v_first.k < v_first.d and v_second.k > v_second.d and
             v_start_track_dead_cross_stage = 1 then
            v_temp_buy_time    := v_second.end_time;
            v_temp_buy_price   := v_second.close_price;
            v_temp_buy_k       := v_second.k;
            v_temp_buy_d       := v_second.d;
            v_dead_cross_found := 1;
            -- 当金叉发生后，只可能发生死叉，因此要将v_start_track_dead_cross_stage设置为0
            v_start_track_dead_cross_stage := 0;
          
          end if;
          -- 插入数据
          if v_gold_cross_found = 1 and v_dead_cross_found = 1 and
             v_temp_sell_time is not null and v_temp_buy_time is not null and
             v_temp_code is not null then
            v_temp_profit_loss := round((v_temp_sell_price -
                                        v_temp_buy_price) /
                                        v_temp_sell_price,
                                        4) * 100;
            -- 获取最近一次交易后的accumulative_profit_loss
            begin
              select t.accumulative_profit_loss
                into v_init_last_acc_profit_loss
                from (select *
                        from mdl_c_f_hour_kd_dead_cross t
                       where t.code = v_code
                       order by t.buy_time desc) t
               where rownum <= 1;
            exception
              when no_data_found then
                dbms_output.put_line('code为【' || v_code || '】，
                                                            在mdl_c_f_hour_kd_dead_cross表中没有记录');
            end;
            -- 计算本次交易后的accumulative_profit_loss
            v_init_last_acc_profit_loss := v_init_last_acc_profit_loss *
                                           (1 + v_temp_profit_loss / 100);
          
            insert into MDL_C_F_HOUR_KD_DEAD_CROSS
              (buy_time,
               sell_time,
               buy_price,
               sell_price,
               profit_loss,
               code,
               accumulative_profit_loss,
               buy_k,
               buy_d,
               sell_k,
               sell_d)
            values
              (v_temp_buy_time,
               v_temp_sell_time,
               v_temp_buy_price,
               v_temp_sell_price,
               v_temp_profit_loss,
               v_temp_code,
               v_init_last_acc_profit_loss,
               v_temp_buy_k,
               v_temp_buy_d,
               v_temp_sell_k,
               v_temp_sell_d);
          
            v_gold_cross_found := 0;
            v_dead_cross_found := 0;
          end if;
        end if;
      end loop;
    end loop;
    commit;
  end CAL_MDL_C_F_KD_DEAD_CROSS_INCR;

end PKG_MODEL_C_F_HOUR;